import * as THREE from 'three';

import Stats from 'three/examples/jsm/libs/stats.module';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

import {Thing} from './thing'
import {TreeSideBoxGeometry} from './TreeSideBoxGeometry';

import data from './data.json'

export class PlantScene {

    parameters:any = null;
    container: HTMLElement | null = null;

    stats: any;

    camera: THREE.PerspectiveCamera | null = null;
    scene: THREE.Scene | null = null;
    renderer: THREE.WebGLRenderer | null = null;

    onWindowResize: any;
    onWindowMousedown: any;

    things: Array<Thing> = [];

    constructor() {
        
        
    }

    /**
     * 创建几何形状
     */
    createArea(x: number, y: number, width: number, height: number) {
        let scene = this.scene;
        const rollOverGeo = new TreeSideBoxGeometry(width, 50, height);

        const coneEdges = new THREE.EdgesGeometry( rollOverGeo);
        var edgesMtl =  new THREE.LineBasicMaterial({color: 0x000000});
        let rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff,side: THREE.DoubleSide } );
        let rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
        const boundingBox = new THREE.LineSegments(coneEdges, edgesMtl);

        x = x + width / 2;
        y = y + height / 2;
        boundingBox.position.set(x, 25, y);
        scene?.add(boundingBox);
        rollOverMesh.position.set(x, 25, y);
        scene?.add( rollOverMesh );
    }
 
    init(el:any) {

        this.container = el;

        // 场景
        const scene = this.scene = new THREE.Scene();

        // const gridHelper = new THREE.GridHelper( 3000, 60 );
		// scene.add( gridHelper );

        scene.add( new THREE.AxesHelper( 2000 ) );

        console.log('data', data);

        const geometry = new THREE.PlaneGeometry( 10000, 10000 );
        geometry.rotateX( - Math.PI / 2 );

        let plane = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: 0xffffff,side: THREE.DoubleSide } ) );
        plane.position.set(0, -5, 0);
        scene.add( plane );


        let x = 30;
        let y = 40;
        let width = 150;
        let height = 300;
        this.createArea(x, y, width, height);

        // 渲染器
        const renderer = this.renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true });
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(this.container.offsetWidth, this.container.offsetHeight);
        renderer.toneMapping = THREE.ACESFilmicToneMapping;
        renderer.shadowMap.enabled = true
        renderer.shadowMap.type = THREE.VSMShadowMap
        this.container.appendChild(renderer.domElement);

        // 相机
        let camera = this.camera = new THREE.PerspectiveCamera(15, this.container.offsetWidth / this.container.offsetHeight, 1, 20000);
        camera.position.set(4200, 8800, 8000);

        // 相机轨道控制器
        let controls: OrbitControls = new OrbitControls(camera, this.renderer.domElement);
        
        controls.maxPolarAngle = Math.PI * 0.495;
        // controls.enablePan = false
        controls.target.set(800, 50, 500);
        controls.maxDistance = 4000.0;
        controls.update();

        // 性能监视器
        const stats = this.stats = Stats();
        this.container.appendChild(stats.dom);

        // 开启渲染
        this.animate();

        let that = this;

        const onWindowResize = this.onWindowResize = function() {
            if (that.container) {
                camera.aspect = that.container?.offsetWidth / that.container?.offsetHeight;
                camera.updateProjectionMatrix();
                that.renderer?.setSize(that.container.offsetWidth, that.container.offsetHeight);
            }
            
        }
        window.addEventListener('resize', onWindowResize);

        const onWindowMousedown = this.onWindowMousedown = function(event:any) {
            const raycaster = new THREE.Raycaster();
            const pointer = new THREE.Vector2();

            pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
            pointer.y = - (event.clientY / window.innerHeight) * 2 + 1;

            raycaster.setFromCamera(pointer, camera)

        }
        window.addEventListener('mousedown', onWindowMousedown);

    }

    addThing(thing: Thing) {
        this.things.push(thing);
    }

    animate() {
        requestAnimationFrame(()=> {
            this.animate();
        });
        this.render();
        this.stats.update();
    }

    render() {
        if (this.camera && this.scene && this.renderer) {
            this.renderer.render(this.scene, this.camera);
        }

    }

    clear() {

        if (this.onWindowResize) {
            window.removeEventListener('resize', this.onWindowResize)
        }
        if (this.onWindowMousedown) {
            window.removeEventListener('mousedown', this.onWindowMousedown);
        }
        
    
        if (this.scene) {
            this.scene.traverse((child: any) => {
    
                if (child.isMesh) {
                    if (child.geometry) child.geometry.dispose();
                    if (child.material) child.material.dispose();
                    child.clear();
                }
            });
        }
    
    }
    
}



function createDiv(imgUrl: string, innerHTML: string) {

	const labelDiv = document.createElement("div");
	labelDiv.style.width = '163px'
	labelDiv.style.height = '50px'
	labelDiv.style.backgroundImage = imgUrl
	labelDiv.style.textAlign = 'center'
	labelDiv.style.verticalAlign = 'center'
	labelDiv.style.color = '#ffffff'
	labelDiv.style.borderRadius = '25px'
	const div = document.createElement('div')
	div.innerHTML = innerHTML
	div.style.fontSize = '14px'
	div.style.width = '113px'
	div.style.marginLeft = '40px'
	div.style.height = '25px'
	div.style.lineHeight = '50px'
	labelDiv.appendChild(div)
	return labelDiv
}


